package com.applet.mallappletbackstage.service.impl;

import com.applet.mallappletbackstage.entity.Nation;
import com.applet.mallappletbackstage.entity.ReleaseWork;
import com.applet.mallappletbackstage.entity.User;
import com.applet.mallappletbackstage.entity.WorkType;
import com.applet.mallappletbackstage.entity.vo.*;
import com.applet.mallappletbackstage.handler.exception.GlobalExceptionHandler;
import com.applet.mallappletbackstage.mapper.ReleaseWorkMapper;
import com.applet.mallappletbackstage.mapper.UserMapper;
import com.applet.mallappletbackstage.service.NationService;
import com.applet.mallappletbackstage.service.UserReleaseWorkService;
import com.applet.mallappletbackstage.service.UserService;
import com.applet.mallappletbackstage.service.WorkTypeService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import net.sf.json.JSONObject;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import java.text.DecimalFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author ${author}
 * @since 2020-07-31
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    public static final String DEF_CHATSET = "UTF-8";
    public static final int DEF_CONN_TIMEOUT = 30000;
    public static final int DEF_READ_TIMEOUT = 30000;
    public static String userAgent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36";

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private UserReleaseWorkService userReleaseWorkService;
    @Autowired
    private ReleaseWorkMapper releaseWorkMapper;
    @Autowired
    private NationService nationService;
    @Autowired
    private WorkTypeService workTypeService;
    @Autowired
    private UserMapper userMapper;

    /***
     * 通过id查询用户信息
     * @param id
     * @return
     */
    @Override
    public UserInfoVO userInfo(String id) {
        //查询数据库用户信息数据
        User user = baseMapper.selectById(id);
        //new UserInfoVO
        UserInfoVO userInfoVO = new UserInfoVO();
        //copy
        BeanUtils.copyProperties(user, userInfoVO);
        return userInfoVO;
    }

    /***
     * 通过用户id查询用户发布工作列表
     * @param id
     * @return
     */
    @Override
    public List<ReleaseWork> userReleaseWorkListById(String id) {
        //通过用户发布工作关联表查询工作
        List<String> releaseWorkIds = userReleaseWorkService.selectReleaseWorkListByUserId(id);
        ArrayList<ReleaseWork> releaseWorks = new ArrayList<>();
        //遍历
        for (String releaseWorkId : releaseWorkIds) {
            ReleaseWork releaseWork = releaseWorkMapper.selectById(releaseWorkId);
            releaseWorks.add(releaseWork);
        }
        return releaseWorks;
    }

    /***
     * 注册用户
     * @param openid
     * @return
     */
    @Override
    public int register(String openid, String nickName, String avatarUrl) {
        User user = new User();
        user.setOpenId(openid);
        user.setNickName(nickName);
        user.setAvatarUrl(avatarUrl);
        return baseMapper.insert(user);
    }

    /***
     * 查询用户是否存在
     * @param openid
     * @return
     */
    @Override
    public User selectIsUser(String openid) {
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("open_id", openid);
        User user = baseMapper.selectOne(userQueryWrapper);
        return user;
    }

    /***
     * 用户登录
     * @param username
     * @param password
     * @return
     */
    @Override
    public boolean login(String username, String password) {
        //条件构造
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("username", username);
        //获取用户信息
        User user = baseMapper.selectOne(userQueryWrapper);
        //获取密码
        String userPassword = user.getPassword();
        boolean checkpw = BCrypt.checkpw(password, userPassword);
        if (!checkpw) {
            return false;
        }
        return true;
    }

    /***
     * 添加用户
     * @param username
     * @param password
     * @param nickname
     * @return
     */
    @Override
    public int addUser(String username, String password, String nickname, String phone, String code) {
        User user = new User();
        user.setUsername(username);
        user.setNickName(nickname);
        user.setPhone(phone);
        user.setPassword(BCrypt.hashpw(password, BCrypt.gensalt()));
        String codeStr = this.stringRedisTemplate.boundValueOps(phone).get();
        if (codeStr.equals(code)) {
            return baseMapper.insert(user);
        }
        return 0;
    }

    /***
     * 完善个人信息
     * @param openid
     * @param uInfoVO
     * @return
     */
    @Override
    public int uInfo(String openid, UInfoVO uInfoVO) {
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("open_id", openid);
        String nation = uInfoVO.getNation();
        String workType = uInfoVO.getWorkType();
        Nation nationResult = nationService.getNation(Integer.valueOf(nation) + 1);
        if (!StringUtils.isEmpty(workType)) {
            WorkType workTypeOne = workTypeService.getWorkTypeOne(Integer.valueOf(workType) + 1);
            User user = new User();
            BeanUtils.copyProperties(uInfoVO, user);
            user.setNation(nationResult.getNation());
            user.setWorkType(workTypeOne.getType());
            int update = baseMapper.update(user, userQueryWrapper);
            return update;
        }
        User user = new User();
        BeanUtils.copyProperties(uInfoVO, user);
        user.setNation(nationResult.getNation());
        int update = baseMapper.update(user, userQueryWrapper);
        return update;
    }

    /***
     * 通过openid查询用户信息
     * @param openid
     * @return
     */
    @Override
    public UInfoVO info(String openid) {
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("open_id", openid);
        User user = baseMapper.selectOne(userQueryWrapper);
        UInfoVO uInfoVO = new UInfoVO();
        BeanUtils.copyProperties(user, uInfoVO);
        if (user.getGender().equals(1)) {
            uInfoVO.setSex("男");
        } else {
            uInfoVO.setSex("女");
        }

        return uInfoVO;
    }

    /***
     * 通过openid查询用户信息
     * @param openid
     * @return
     */
    @Override
    public User getInfo(String openid) {
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("open_id", openid);
        User user = baseMapper.selectOne(userQueryWrapper);
        return user;
    }

    /***
     * 完善用户资料
     * @param openId
     * @param perfectInfoVO
     * @return
     */
    @Override
    public int perfectInfo(String openId, PerfectInfoVO perfectInfoVO) {
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("open_id", openId);
        String username = perfectInfoVO.getUsername();
        String password = perfectInfoVO.getPassword();
        String BCPassword = BCrypt.hashpw(password, BCrypt.gensalt());
        User user = new User();
        user.setUsername(username);
        user.setPassword(BCPassword);
        int update = baseMapper.update(user, userQueryWrapper);
        return update;
    }

    /***
     * 查询所有用户数据
     * @param openId
     * @return
     */
    @Override
    public User getAllUserInfo(String openId) {
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("open_id", openId);
        User user = baseMapper.selectOne(userQueryWrapper);
        return user;
    }

    /***
     * 获取个人信息
     * @param openId
     * @return
     */
    @Override
    public PersonalInfoVO getUserInfo(String openId) {
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("open_id", openId);
        User user = baseMapper.selectOne(userQueryWrapper);
        if (null == user) {
            return null;
        }
        PersonalInfoVO personalInfoVO = new PersonalInfoVO();
        BeanUtils.copyProperties(user, personalInfoVO);
        return personalInfoVO;
    }

    /**
     * 获取用户列表
     *
     * @param current
     * @return
     */
    @Override
    public Page<User> getUserList(Long current) {
        Page<User> userPage = new Page<>(current, 15);
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        return userMapper.selectPage(userPage, userQueryWrapper);
    }

    /**
     * 拉黑用户
     *
     * @return
     */
    @Override
    public void deleteUser(String user) {
        userMapper.deleteById(user);
    }

    /**
     * 获取用户列表
     *
     * @param current
     * @return
     */
    @Override
    public Page<User> getUserListByDate(Long current, AdminSearch adminSearch) {
        Page<User> userPage = new Page<>(current, 15);
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.between("gmt_create", adminSearch.getBegin(), adminSearch.getEnd());
        return userMapper.selectPage(userPage, userQueryWrapper);
    }

    /***
     * 发送验证码
     * @param phone
     * @return
     */
    @Override
    public int sendCode(String phone) {
        DecimalFormat sixdf = new DecimalFormat("000000");
        Random random = new Random();
        String format = sixdf.format(random.nextInt(1000000));
        this.stringRedisTemplate.boundValueOps(phone).set(format, 30, TimeUnit.SECONDS);
        String result = null;
        String url = "http://v.juhe.cn/sms/send";//请求接口地址
        Map params = new HashMap();//请求参数
        params.put("mobile", phone);//接受短信的用户手机号码
        params.put("tpl_id", "29708");//您申请的短信模板ID，根据实际情况修改
        params.put("tpl_value", "#code#=" + format);//您设置的模板变量，根据实际情况修改
        params.put("key", "5829b6c962f915b1c637038e9eb971ad");//应用APPKEY(应用详细页查询)
        try {
            result = net(url, params, "GET");
            JSONObject object = JSONObject.fromObject(result);
            if (object.getInt("error_code") == 0) {
                System.out.println(object.get("result"));
            } else {
                System.out.println(object.get("error_code") + ":" + object.get("reason"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 1;
    }

    /**
     * @param strUrl 请求地址
     * @param params 请求参数
     * @param method 请求方法
     * @return 网络请求字符串
     * @throws Exception
     */
    public static String net(String strUrl, Map params, String method) throws Exception {
        HttpURLConnection conn = null;
        BufferedReader reader = null;
        String rs = null;
        try {
            StringBuffer sb = new StringBuffer();
            if (method == null || method.equals("GET")) {
                strUrl = strUrl + "?" + urlencode(params);
            }
            URL url = new URL(strUrl);
            conn = (HttpURLConnection) url.openConnection();
            if (method == null || method.equals("GET")) {
                conn.setRequestMethod("GET");
            } else {
                conn.setRequestMethod("POST");
                conn.setDoOutput(true);
            }
            conn.setRequestProperty("User-agent", userAgent);
            conn.setUseCaches(false);
            conn.setConnectTimeout(DEF_CONN_TIMEOUT);
            conn.setReadTimeout(DEF_READ_TIMEOUT);
            conn.setInstanceFollowRedirects(false);
            conn.connect();
            if (params != null && method.equals("POST")) {
                try {
                    DataOutputStream out = new DataOutputStream(conn.getOutputStream());
                    out.writeBytes(urlencode(params));
                } catch (Exception e) {
                    // TODO: handle exception
                    e.printStackTrace();
                }
            }
            InputStream is = conn.getInputStream();
            reader = new BufferedReader(new InputStreamReader(is, DEF_CHATSET));
            String strRead = null;
            while ((strRead = reader.readLine()) != null) {
                sb.append(strRead);
            }
            rs = sb.toString();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                reader.close();
            }
            if (conn != null) {
                conn.disconnect();
            }
        }
        return rs;
    }

    //将map型转为请求参数型
    public static String urlencode(Map<String, String> data) {
        StringBuilder sb = new StringBuilder();
        for (Map.Entry i : data.entrySet()) {
            try {
                sb.append(i.getKey()).append("=").append(URLEncoder.encode(i.getValue() + "", "UTF-8")).append("&");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }
}
